// // 防抖实现

// function deBounce(fn,wait){
//   let timeout=null

//   return function deBounced(...args){
//     console.log(...args)
//     if(timeout){
//       clearTimeout(timeout)
//       timeout=null
//     }

//     timeout=setTimeout(function(){
//       fn(...args)
//     },wait)
//   }
// }

// function aa(){
//   console.log("aaaaa")
//   console.log(arguments)
// }

// var fn=deBounce(aa,2000)
// fn([1,2,3,4,5,6])
// // fn()
// // fn()
// // fn()


const throttle=(func,wait=0)=>{
  let timeout=null
  let args
  let firstCallTimestamp

  function throttled(...arg) {
    if (!firstCallTimestamp) firstCallTimestamp = new Date().getTime()
    if (!args) {
      console.log('set args:', arg)
      args = arg
    }
 
    if (timeout) {
      clearTimeout(timeout)
      timeout = null
    }
 
    // 以Promise的形式返回函数执行结果
    return new Promise(async(res, rej) => {
      if (new Date().getTime() - firstCallTimestamp >= wait) {
        try {
          const result = await func.apply(this, args)
          res(result)
        } catch (e) {
          rej(e)
        } finally {
          cancel()
        }
      } else {
        timeout = setTimeout(async () => {
          try {
            const result = await func.apply(this, args)
            res(result)
          } catch (e) {
            rej(e)
          } finally {
            cancel()
          }
        }, firstCallTimestamp + wait - new Date().getTime())  // 计算下一个指定时间
      }
    })
  }
 
  // 允许取消
  function cancel() {
    clearTimeout(timeout)
    args = null
    timeout = null
    firstCallTimestamp = null
  }
 
  // 允许立即执行
  function flush(...arg) {
    cancel()
    
    console.log("flush()")
    return func.apply(this, arg)
  }
 
  throttled.cancel = cancel
  throttled.flush = flush
 
  return throttled
}


function bb(){
  console.log("...arguments")
  console.log(...arguments)
}

// var fun=throttle(bb,3000);
// fun([1,2,3,4,5]);


var fun=throttle(bb,3000);
fun([1,2,3,4,5]);//延迟执行
fun.flush([1,2,3,4,5]);//立即执行